package com.kexio.security.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.kexio.security.domain.User;
import com.kexio.security.domain.enums.UserStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 用户输出DTO（统一输出对象）
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Data
@Schema(description = "用户输出DTO")
public class UserDTO {

    /**
     * 用户ID
     */
    @Schema(description = "用户ID", example = "1")
    private Long id;

    /**
     * 用户名
     */
    @Schema(description = "用户名", example = "admin")
    private String username;

    /**
     * 昵称
     */
    @Schema(description = "昵称", example = "管理员")
    private String nickname;

    /**
     * 真实姓名
     */
    @Schema(description = "真实姓名", example = "张三")
    private String realName;

    /**
     * 邮箱
     */
    @Schema(description = "邮箱", example = "admin@kexio.com")
    private String email;

    /**
     * 手机号
     */
    @Schema(description = "手机号", example = "13800138000")
    private String phone;

    /**
     * 头像URL
     */
    @Schema(description = "头像URL", example = "https://example.com/avatar.jpg")
    private String avatar;

    /**
     * 用户状态
     */
    @Schema(description = "用户状态", example = "1")
    private Integer status;

    /**
     * 用户状态描述
     */
    @Schema(description = "用户状态描述", example = "激活")
    private String statusDesc;

    /**
     * 部门ID
     */
    @Schema(description = "部门ID", example = "1")
    private Long deptId;

    /**
     * 部门名称
     */
    @Schema(description = "部门名称", example = "技术部")
    private String deptName;

    /**
     * 岗位ID
     */
    @Schema(description = "岗位ID", example = "1")
    private Long positionId;

    /**
     * 岗位名称
     */
    @Schema(description = "岗位名称", example = "高级工程师")
    private String positionName;

    /**
     * 最后登录时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "最后登录时间", example = "2024-01-01 12:00:00")
    private LocalDateTime lastLoginTime;

    /**
     * 最后登录IP
     */
    @Schema(description = "最后登录IP", example = "192.168.1.1")
    private String lastLoginIp;

    /**
     * 登录次数
     */
    @Schema(description = "登录次数", example = "10")
    private Integer loginCount;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "创建时间", example = "2024-01-01 10:00:00")
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "更新时间", example = "2024-01-01 11:00:00")
    private LocalDateTime updatedTime;

    /**
     * 创建者
     */
    @Schema(description = "创建者ID", example = "1")
    private Long createdBy;

    /**
     * 更新者
     */
    @Schema(description = "更新者ID", example = "1")
    private Long updatedBy;

    /**
     * 租户ID
     */
    @Schema(description = "租户ID", example = "1")
    private Long tenantId;

    /**
     * 备注
     */
    @Schema(description = "备注", example = "系统管理员")
    private String remark;

    // ==================== 静态工厂方法 ====================

    /**
     * 从User实体创建DTO
     * @param user 用户实体
     * @return 用户DTO
     */
    public static UserDTO fromEntity(User user) {
        if (user == null) {
            return null;
        }

        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setNickname(user.getNickname());
        dto.setRealName(user.getRealName());
        dto.setEmail(user.getEmail());
        dto.setPhone(user.getPhone());
        dto.setAvatar(user.getAvatar());
        dto.setStatus(user.getStatus());
        dto.setDeptId(user.getDeptId());
        dto.setPositionId(user.getPositionId());
        dto.setLastLoginTime(user.getLastLoginTime());
        dto.setLastLoginIp(user.getLastLoginIp());
        dto.setLoginCount(user.getLoginCount());
        dto.setCreatedTime(user.getCreatedTime());
        dto.setUpdatedTime(user.getUpdatedTime());
        dto.setCreatedBy(user.getCreatedBy());
        dto.setUpdatedBy(user.getUpdatedBy());
        dto.setTenantId(user.getTenantId());
        dto.setRemark(user.getRemark());

        // 设置状态描述
        UserStatus userStatus = user.getUserStatus();
        if (userStatus != null) {
            dto.setStatusDesc(userStatus.getDescription());
        }

        return dto;
    }

    /**
     * 创建简单用户信息DTO（用于下拉框等场景）
     * @param user 用户实体
     * @return 简单用户DTO
     */
    public static UserDTO createSimple(User user) {
        if (user == null) {
            return null;
        }

        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setNickname(user.getNickname());
        dto.setRealName(user.getRealName());
        dto.setAvatar(user.getAvatar());
        dto.setStatus(user.getStatus());

        UserStatus userStatus = user.getUserStatus();
        if (userStatus != null) {
            dto.setStatusDesc(userStatus.getDescription());
        }

        return dto;
    }

    /**
     * 创建用户统计信息DTO
     * @param totalCount 总数
     * @param activeCount 激活数
     * @param disabledCount 禁用数
     * @param lockedCount 锁定数
     * @return 统计DTO
     */
    public static UserDTO createStatistics(Long totalCount, Long activeCount, 
                                          Long disabledCount, Long lockedCount) {
        UserDTO dto = new UserDTO();
        dto.id = totalCount;  // 复用ID字段存储总数
        dto.loginCount = activeCount != null ? activeCount.intValue() : 0;
        // 可以通过扩展字段存储其他统计信息
        return dto;
    }

    // ==================== 便利方法 ====================

    /**
     * 获取用户状态枚举
     * @return 用户状态枚举
     */
    public UserStatus getUserStatus() {
        return UserStatus.fromCode(this.status);
    }

    /**
     * 检查用户是否激活
     * @return 是否激活
     */
    public boolean isActive() {
        UserStatus userStatus = getUserStatus();
        return userStatus != null && userStatus.isActive();
    }

    /**
     * 检查用户是否被禁用
     * @return 是否被禁用
     */
    public boolean isDisabled() {
        UserStatus userStatus = getUserStatus();
        return userStatus != null && userStatus.isDisabled();
    }

    /**
     * 获取显示名称（优先显示昵称，其次真实姓名，最后用户名）
     * @return 显示名称
     */
    public String getDisplayName() {
        if (nickname != null && !nickname.trim().isEmpty()) {
            return nickname;
        }
        if (realName != null && !realName.trim().isEmpty()) {
            return realName;
        }
        return username;
    }

    // ==================== 手写Setter方法 ====================
    
    public void setId(Long id) { this.id = id; }
    public void setUsername(String username) { this.username = username; }
    public void setNickname(String nickname) { this.nickname = nickname; }
    public void setRealName(String realName) { this.realName = realName; }
    public void setEmail(String email) { this.email = email; }
    public void setPhone(String phone) { this.phone = phone; }
    public void setAvatar(String avatar) { this.avatar = avatar; }
    public void setStatus(Integer status) { this.status = status; }
    public void setStatusDesc(String statusDesc) { this.statusDesc = statusDesc; }
    public void setDeptId(Long deptId) { this.deptId = deptId; }
    public void setDeptName(String deptName) { this.deptName = deptName; }
    public void setPositionId(Long positionId) { this.positionId = positionId; }
    public void setPositionName(String positionName) { this.positionName = positionName; }
    public void setLastLoginTime(LocalDateTime lastLoginTime) { this.lastLoginTime = lastLoginTime; }
    public void setLastLoginIp(String lastLoginIp) { this.lastLoginIp = lastLoginIp; }
    public void setLoginCount(Integer loginCount) { this.loginCount = loginCount; }
    public void setCreatedTime(LocalDateTime createdTime) { this.createdTime = createdTime; }
    public void setUpdatedTime(LocalDateTime updatedTime) { this.updatedTime = updatedTime; }
    public void setCreatedBy(Long createdBy) { this.createdBy = createdBy; }
    public void setUpdatedBy(Long updatedBy) { this.updatedBy = updatedBy; }
    public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
    public void setRemark(String remark) { this.remark = remark; }
}